package com.cwj;

/**
 * 给定一个数，求与该数二进制表示中1的个数相同的较大、较小数。
 * @author chenwujie
 * @date 2020/09/279:23
 */
public class AESTest {
    public static void main(String[] args) {
        AESTest aesTest = new AESTest();
        int[] closedNumbers = aesTest.findClosedNumbers(1837591841);
        System.out.println(closedNumbers[0]);
        System.out.println(closedNumbers[1]);
    }
    public int[] findClosedNumbers(int num) {
        int[] arr = new int[2];
        arr[0] = -1;
        arr[1] = -1;
        int mask = num ^ (num >>> 1);
        if(mask == 0){
            return arr;
        }
        int mask1 = mask & -mask;
        int mask2 = mask - mask1;
        if((mask1 & num) == mask1){
            // 较大
            arr[0] = larger(num, mask1);
            // 较小
            if(mask2 != 0){
                arr[1] = smaller(num, mask2);
            }
        }else{
            // 较小
            arr[1] = smaller(num, mask1);
            if(mask2 != 0){
                // 较大
                arr[0] = larger(num, mask2);
            }
        }
        return arr;
    }

    public int smaller(int num , int mask){
        int smaller = -1;
        int maskBitCount = Integer.bitCount(mask -1);
        // 末尾的数
        int end = num & (mask -1);
        // 10之后的位置0 ;交换10 为01
        smaller = num ^ end ^ (mask + (mask << 1));
        // 设置最小的末尾数
        int endBitCount = Integer.bitCount(end);
        smaller |= ((1 << Integer.bitCount(end)) - 1) << (maskBitCount - endBitCount);
        return smaller;
    }

    public int larger(int num , int mask){
        int larger = -1;
        // 末尾的数
        int end = num & (mask -1);
        // 01之后的位置0 ;交换01 为10
        larger = num ^ end ^ (mask + (mask << 1));
        // 设置最小的末尾数
        larger |= ((1 << Integer.bitCount(end)) - 1);
        return larger;
    }
}
